package com.idreems.AMapLocation;

import java.util.Set;
import java.util.WeakHashMap;

import android.app.Activity;
import android.location.Location;
import android.os.Bundle;
import android.util.Log;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.location.LocationManagerProxy;
import com.amap.api.location.LocationProviderProxy;

public class LocationManager {
    private static LocationManager sLocationManager;
    private static final String TAG = "LocationManager";
    private static final float MIN_DISTANCE = 100;
    private static final long MIN_TIME = 1000;

    private LocationManagerProxy mAMapLocManager = null;
    
    private boolean mMonitoringLocation;
    private AMapLocation mLocation;
    private WeakHashMap<AMapLocationListener, String> mOuterListeners = new WeakHashMap<AMapLocationListener, String>();
    private AMapLocationListener mMapLocationListener = new AMapLocationListener() {
        @Override
        public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
        }

        @Override
        public void onProviderEnabled(String arg0) {
        }

        @Override
        public void onProviderDisabled(String arg0) {
        }

        @Override
        public void onLocationChanged(Location arg0) {
        }

        @Override
        public void onLocationChanged(AMapLocation loc) {
            mLocation = loc;
            Set<AMapLocationListener> set = mOuterListeners.keySet();
            for (AMapLocationListener listener : set) {
                if (listener != null) {
                    listener.onLocationChanged(loc);
                }
            }
        }
    };

    public synchronized static LocationManager sharedInstance() {
        if (sLocationManager == null) {
            sLocationManager = new LocationManager();
        }
        return sLocationManager;
    }

    private LocationManager() {
    }

    public void requestLocationUpdates(Activity activity, AMapLocationListener listener) {
        if (mAMapLocManager == null) {
            mAMapLocManager = LocationManagerProxy.getInstance(activity);
        }
        startLocatingMyLocation();
        mOuterListeners.put(listener, "");
    }

    public void removeUpdates(AMapLocationListener listener) {
        mOuterListeners.remove(listener);
    }

    private boolean startLocatingMyLocation() {
        if (!mMonitoringLocation && mAMapLocManager.isProviderEnabled(LocationProviderProxy.AMapNetwork)) {
            mAMapLocManager.requestLocationUpdates(LocationProviderProxy.AMapNetwork, MIN_TIME, MIN_DISTANCE, mMapLocationListener);
            mMonitoringLocation = true;
        }
        return mMonitoringLocation;
    }

    public void stopLocatingMyLocation() {
        if (mMonitoringLocation && mAMapLocManager != null) {
            mMonitoringLocation = false;
            mAMapLocManager.removeUpdates(mMapLocationListener);
        }
    }

    public void destroy() {
        stopLocatingMyLocation();
        if (mAMapLocManager != null) {
            mAMapLocManager.destory();
        }
        mAMapLocManager = null;
        mLocation = null;
    }

    public AMapLocation getLocation() {
        Log.d(TAG, "location: " + mLocation);
        return mLocation;
    }
}
